package com.dctp.common.intercept;

import com.alibaba.fastjson.JSON;
import com.dctp.common.core.RedisManager;
import com.dctp.common.utils.IPUtil;
import com.dctp.common.utils.MapUtil;
import com.dctp.common.utils.NumberUtil;
import com.dctp.common.utils.StringUtil;
import com.dctp.common.vo.JsonResult;
import com.dctp.common.vo.TipCode;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.core.Controller;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import static com.dctp.common.vo.TipCode.*;


public class ApiAuthInterceptor implements Interceptor {

	private static final Logger logger = LoggerFactory.getLogger(ApiAuthInterceptor.class);

	private static final List<String> whiteApiList = Arrays.asList(
			"/user/login",
			"/user/sendCode",
			"/version/checkUpdate",
			"/user/validateCode",
			"/user/validateInviteCode",
			"/user/forgotPassword",
			"/user/register");

	@Override
	public void intercept(Invocation invocation) {

		try {
			Controller controller = invocation.getController();
			HttpServletRequest request = invocation.getController().getRequest();
			String remoteIp = IPUtil.getClientIP(controller);
			Long num = RedisManager.getInstance().incrBy(remoteIp,1L);

			Integer qps = NumberUtil.parseInt(RedisManager.getInstance().get("api_qps"),50);
			if (num > qps) {
				logger.error("ip:{}，请求过于频繁",remoteIp);
				IPUtil.trace(remoteIp,1);
				controller.renderJson(JsonResult.fail(TipCode.FUCK_CODE));
				return;
			}
			RedisManager.getInstance().del(remoteIp);
			String uri = request.getRequestURI().replace(request.getContextPath(),"");
			String userToken = request.getHeader("usrtk");

			if (StringUtil.isEmpty(userToken)) {
				if (whiteApiList.contains(uri)) {
					invocation.invoke();
				}else {
					controller.renderJson(JsonResult.fail(NOT_LOGIN));
					return;
				}
			}else {
				Record user = Db.findFirst("select * from dctp_user where token = ? ", userToken);
				if (null == user) {
					IPUtil.trace(remoteIp, 2);
					logger.info("remoteId :{} , token :{} not correct ",remoteIp,userToken);
					controller.renderJson(JsonResult.fail(NOT_REGISTER));
					return;
				}

				if (user.getInt("status") == 0) {
					controller.renderJson(JsonResult.fail(STATUS_ILLEGAL));
					return;
				}
				invocation.getController().set("reqUser", user);
			}
			invocation.invoke();
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			Controller controller = invocation.getController();
			controller.renderJson(JSON.toJSONString(MapUtil.ofImmutable(MapUtil.entry("status",e.getMessage()))));
		}
	}
}
